
#include "replay.h"

using namespace WtfEngine;

void Replay::setStatus(Replay::tStatus st)
{
	if(st != STOP && mStatus == STOP) {
		IDynamic::Init();
	} else if(mStatus != STOP) {
		IDynamic::Destroy();
	};
	mStatus = st;
};

/**
 * Sets the playback pointer to the frame at the given time
 **/
void Replay::Navigate(WtfEngine::tGameTime time)
{
	unsigned i, j;
	for(i = 0, j = mNumFrames; i < j; ) {
		unsigned m = (i + j + 1) / 2;
		tGameTime ft = mvFrameBlocks[m / FrameBlock::MaxSubFrames]
		                ->mvSubFrames[m % FrameBlock::MaxSubFrames].mGameTime;
		
		if(time < ft) {
			j = m;
		} else {
			i = m;
			if(time == ft) break;
		};
	};

	mCurrentFrame = i;
}

void Replay::UpdatePlayback(tGameTime dt) {
	assert (mCurrentFrame + 1 < mNumFrames);
	
	Frame& frame(mvFrameBlocks[(mCurrentFrame + 1) / FrameBlock::MaxSubFrames]
	              ->mvSubFrames[(mCurrentFrame + 1) % FrameBlock::MaxSubFrames]);
	
	if(mReplayTime >= frame.mGameTime) {
		// Advance to next frame
		mCurrentFrame++;	
		GameManager::GetInstance().DeserializeGame(frame.mrFrameUpdate, GameManager::GAME_UPDATE_ALL);
	};
};

void Replay::CaptureFrame(tGameTime dt) {
	unsigned iFrame = unsigned(mReplayTime / mReplayDelta);
	if(iFrame > mCurrentFrame) {
		// Capture new frame

		if(iFrame >= mNumFrames) {

		};
	};
};

void Replay::Update()
{
	tGameTime dt = Kernel::GetInstance().GetGameState()->GetDelta();
	if(dt > 0) {
		switch (mStatus) {
		case RECORD:
			CaptureFrame(dt);
			break;
		case PLAY:
			UpdatePlayback(dt);
			break;
		default:
			IDynamic::Destroy();
			return;
		};

		mReplayTime += dt;
	};
};
